package com.cloudbroker.bsc.common.search.elasticsearch;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.common.configure.ConfigUtil;
import com.cloudbroker.bsc.common.search.core.SearchEngineEntity;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

import java.net.UnknownHostException;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * ES 搜所引擎 基本功能
 *
 * @create 2016-6-11
 * @author moyin18602
 * @version
 */
public class ElasticsearchBase extends AbstractElasticsearch {
	public static String DATABASE_NAME;
	
	public <T> boolean save(String database_name, String table_name, String row_id, T obj){
		// TODO Auto-generated method stub
		String jsonValue = JSON.toJSONString(obj);
		IndexResponse response = null;
		Client client = null;
		try {
			client = getClient();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

		response = client.prepareIndex(database_name, table_name, row_id).setSource(jsonValue).execute().actionGet();
		return true;
	}

	public <T> boolean save(List<T> list){
		Client client = null;
		try {
			client = getClient();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		BulkRequestBuilder bulkRequest = client.prepareBulk();

		for (Object obj: list) {
			ElasticsearchEntity entity = (ElasticsearchEntity)obj;
			bulkRequest.add(client.prepareIndex(entity.getDatabase_name(), entity.getTable_name(), entity.getRow_id())
					.setSource(JSON.toJSONString(entity.getObj())
					)
			);
		}
		BulkResponse bulkResponse = bulkRequest.execute().actionGet();
		return !bulkResponse.hasFailures();
	}

	public boolean save(SearchEngineEntity entity) {
		String database_name = entity.getDatabase_name();
		String table_name = entity.getTable_name();
		String row_id = entity.getRow_id();

		// TODO Auto-generated method stub
		String jsonValue = JSON.toJSONString(entity.getObj());
		IndexResponse response = null;
		try {
			response = getClient().prepareIndex(database_name, table_name, row_id).setSource(jsonValue).execute().actionGet();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return response.isCreated();
	}


	@SuppressWarnings("rawtypes")
	public <T> boolean update(String database_name, String  table_name, String  row_id, T obj){
		UpdateResponse response = null;
		String jsonValue = JSON.toJSONString(obj);
		UpdateRequest updateRequest = new UpdateRequest(database_name, table_name, row_id).doc(jsonValue);
		Client client = null;
		try {
			client = getClient();
			response = client.update(updateRequest).get();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	public boolean update(SearchEngineEntity entity) {
		String database_name = entity.getDatabase_name();
		String table_name = entity.getTable_name();
		String row_id = entity.getRow_id();

		UpdateResponse response = null;
		String jsonValue = JSON.toJSONString(entity.getObj());
		UpdateRequest updateRequest = new UpdateRequest(database_name, table_name, row_id).doc(jsonValue);
		try {
			response = getClient().update(updateRequest).get();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}


	public boolean delete(String database_name, String  table_name, String  row_id) {
		DeleteResponse response = null;
		try {
			response = getClient().prepareDelete(database_name, table_name, row_id).get();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return response.isFound();
	}

	public boolean delete(SearchEngineEntity entity) {
		String database_name = entity.getDatabase_name();
		String table_name = entity.getTable_name();
		String row_id = entity.getRow_id();

		DeleteResponse response = null;
		try {
			response = getClient().prepareDelete(database_name, table_name, row_id).get();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return response.isFound();
	}
//
//	public SearchResponse query(String[] database_names, String[] table_names, SearchType searchType, QueryBuilder queryBuilder,
//			QueryBuilder postFilter, Integer start, Integer limit, Boolean isExplain, String... highLightField) {
//		SearchRequestBuilder requestBuilder = null;
//		//index check
//        if (database_names == null) {
//            try {
//				requestBuilder = getClient().prepareSearch();
//			} catch (UnknownHostException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//        } else {
//            try {
//				requestBuilder = getClient().prepareSearch(database_names);
//			} catch (UnknownHostException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//        }
//
//        //type check
//        if (table_names != null) {
//            requestBuilder = requestBuilder.setTypes(table_names);
//        }
//
//        //searchtype
//        if (searchType != null) {
//            requestBuilder.setSearchType(searchType);
//        }
//
//        //queryBuilder
//        if (null != queryBuilder) {
//            requestBuilder.setQuery(queryBuilder);
//        }
//
//        //postFilter
//        if (null != postFilter) {
//            requestBuilder.setPostFilter(postFilter);
//        }
//
//        //start
//        if (null != start) {
//            requestBuilder.setFrom(start);
//        }
//
//        //limit
//        if (null != limit) {
//            requestBuilder.setSize(limit);
//        }
//
//        //explain
//        if (null != isExplain) {
//            requestBuilder.setExplain(isExplain);
//        }
//
////		requestBuilder.addSort()
//
//        if (null != highLightField) {
//            for (String hLField : highLightField) {
//                requestBuilder.addHighlightedField(hLField);
//            }
//        }
//
//        SearchResponse response = requestBuilder.execute().actionGet();
//        return response;
//	}



	public SearchResponse query(ElasticsearchEntity elasticsearchEntity) {
		SearchRequestBuilder requestBuilder = null;
		//index check
		if (elasticsearchEntity.getDatabase_names() == null) {
			try {
				requestBuilder = getClient().prepareSearch();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			try {
				requestBuilder = getClient().prepareSearch(elasticsearchEntity.getDatabase_names());
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		//type check
		if (elasticsearchEntity.getTable_names() != null) {
			requestBuilder = requestBuilder.setTypes(elasticsearchEntity.getTable_names());
		}

		//searchtype
		if (elasticsearchEntity.getSearchType() != null) {
			requestBuilder.setSearchType(elasticsearchEntity.getSearchType());
		}

		//queryBuilder
		if (null != elasticsearchEntity.getQueryBuilder()) {
			requestBuilder.setQuery(elasticsearchEntity.getQueryBuilder());
		}

		//postFilter
		if (null != elasticsearchEntity.getPostFilter()) {
			requestBuilder.setPostFilter(elasticsearchEntity.getPostFilter());
		}

		//start
		if (null != elasticsearchEntity.getStart()) {
			requestBuilder.setFrom(elasticsearchEntity.getStart());
		}

		//limit
		if (null != elasticsearchEntity.getLimit()) {
			requestBuilder.setSize(elasticsearchEntity.getLimit());
		}

		//explain
		if (null != elasticsearchEntity.getExplain()) {
			requestBuilder.setExplain(elasticsearchEntity.getExplain());
		}

//		requestBuilder.addSort()

		if (null != elasticsearchEntity.getHighLightField()) {
			for (String hLField : elasticsearchEntity.getHighLightField()) {
				requestBuilder.addHighlightedField(hLField);
			}
		}

		if (null != elasticsearchEntity.getField_sort()) {
			SortOrder order;
			if(null != elasticsearchEntity.getSort_order() && elasticsearchEntity.getSort_order().equalsIgnoreCase("DESC")){
				order = SortOrder.DESC;
			}else{
				order = SortOrder.ASC;
			}
			SortBuilder sortBuilder = SortBuilders.fieldSort(elasticsearchEntity.getField_sort())
					.order(order).ignoreUnmapped(true);
			requestBuilder.addSort(sortBuilder);
		}

		SearchResponse response = requestBuilder.execute().actionGet();
		return response;
	}

	public Object deleteAll() throws UnknownHostException {
		return getClient().admin().indices().prepareDelete("_all").execute().actionGet();
		
	}
}
